#!/usr/bin/env bash
# Summary: Configure the shell environment for goenv
# Usage: eval "$(goenv init - [--no-rehash] [<shell>])"

set -e
[ -n "$GOENV_DEBUG" ] && set -x

# Provide goenv completions
if [ "$1" = "--complete" ]; then
  echo -
  echo --no-rehash
  echo bash
  echo fish
  echo ksh
  echo zsh
  exit
fi

print=""
no_rehash=""
for args in "$@"; do
  if [ "$args" = "-" ]; then
    print=1
    shift
  fi

  if [ "$args" = "--no-rehash" ]; then
    no_rehash=1
    shift
  fi
done

shell="$1"
if [ -z "$shell" ]; then
  shell="$(ps -p "$PPID" -o 'args=' 2>/dev/null || true)"
  shell="${shell%% *}"
  shell="${shell##-}"
  shell="${shell:-$SHELL}"
  shell="${shell##*/}"
fi

root="${0%/*}/.."

if [ -z "$print" ]; then
  case "$shell" in
  bash)
    if [ -f "${HOME}/.bashrc" ] && [ ! -f "${HOME}/.bash_profile" ]; then
      profile='~/.bashrc'
    else
      profile='~/.bash_profile'
    fi
    ;;
  zsh)
    profile='~/.zshrc'
    ;;
  ksh)
    profile='~/.profile'
    ;;
  fish)
    profile='~/.config/fish/config.fish'
    ;;
  *)
    profile="<unknown shell: $shell, replace with your profile path>"
    ;;
  esac

  {
    echo "# Load goenv automatically by appending"
    echo "# the following to ${profile}:"
    echo
    case "$shell" in
    fish)
      echo 'status --is-interactive; and source (goenv init -|psub)'
      ;;
    *)
      echo 'eval "$(goenv init -)"'
      ;;
    esac
    echo
  } >&2

  exit 0
fi

mkdir -p "${GOENV_ROOT}/"{shims,versions}

case "$shell" in
fish)
  cat <<'EOL'
set -gx GOENV_SHELL fish
EOL
  echo "set -gx GOENV_ROOT ${GOENV_ROOT}"
  cat <<'EOL'
if test -z $GOENV_RC_FILE
  set GOENV_RC_FILE $HOME/.goenvrc
end
if test -e $GOENV_RC_FILE
  source $GOENV_RC_FILE
end
if not contains $GOENV_ROOT/shims $PATH
  if test "$GOENV_PATH_ORDER" = "front"
    set -gx PATH $GOENV_ROOT/shims $PATH
  else
    set -gx PATH $PATH $GOENV_ROOT/shims
  end
end
EOL

  # Add PATH collision warning unless explicitly disabled
  if [ "${GOENV_DISABLE_PATH_WARNING:-0}" != "1" ]; then
    cat <<'EOL'
if test "$GOENV_PATH_ORDER" != "front"
  set -l system_go_path (command -v go 2>/dev/null)
  if test -n "$system_go_path"; and not string match -q "$GOENV_ROOT*" $system_go_path
    echo "goenv: WARNING: System 'go' found at $system_go_path" >&2
    echo "goenv: Since your shims are at the end of PATH, system 'go' will be used instead of goenv-managed versions." >&2
    echo "goenv: To fix this, add the following to your $GOENV_RC_FILE:" >&2
    echo "goenv:     set -gx GOENV_PATH_ORDER front" >&2
    echo "goenv: Or run: echo 'set -gx GOENV_PATH_ORDER front' >> $GOENV_RC_FILE" >&2
    echo "" >&2
  end
end
EOL
  fi
  ;;
*)
  cat <<EOL
export GOENV_SHELL=${shell}
export GOENV_ROOT=${GOENV_ROOT}
if [ -z "\${GOENV_RC_FILE:-}" ]; then
  GOENV_RC_FILE="\${HOME}/.goenvrc"
fi
if [ -e "\${GOENV_RC_FILE:-}" ]; then
  source "\${GOENV_RC_FILE}"
fi
if [ "\${PATH#*\$GOENV_ROOT/shims}" = "\${PATH}" ]; then
  if [ "\${GOENV_PATH_ORDER:-}" = "front" ] ; then
    export PATH="\${GOENV_ROOT}/shims:\${PATH}"
  else
    export PATH="\${PATH}:\${GOENV_ROOT}/shims"
  fi
fi
EOL

  # Add PATH collision warning unless explicitly disabled
  if [ "${GOENV_DISABLE_PATH_WARNING:-0}" != "1" ]; then
    cat <<'EOL'
if [ "${GOENV_PATH_ORDER:-}" != "front" ]; then
  system_go_path="$(command -v go 2>/dev/null || true)"
  if [ -n "$system_go_path" ]; then
    case "$system_go_path" in
      ${GOENV_ROOT}/*)
        ;;
      *)
        echo "goenv: WARNING: System 'go' found at $system_go_path" >&2
        echo "goenv: Since your shims are at the end of PATH, system 'go' will be used instead of goenv-managed versions." >&2
        echo "goenv: To fix this, add the following to your ${GOENV_RC_FILE}:" >&2
        echo "goenv:     export GOENV_PATH_ORDER=front" >&2
        echo "goenv: Or run: echo 'export GOENV_PATH_ORDER=front' >> ${GOENV_RC_FILE}" >&2
        echo "" >&2
        ;;
    esac
  fi
fi
EOL
  fi
  ;;
esac

completion="${root}/completions/goenv.${shell}"
if [ -r "$completion" ]; then
  echo "source '$completion'"
fi

if [ -z "$no_rehash" ]; then
  echo 'command goenv rehash 2>/dev/null'
fi

commands=($(goenv-commands --sh))
case "$shell" in
fish)
  cat <<EOS
function goenv
  set command \$argv[1]
  set -e argv[1]

  switch "\$command"
  case ${commands[*]}
    source (goenv "sh-\$command" \$argv|psub)
  case '*'
    command goenv "\$command" \$argv
  end
end
EOS
  ;;
ksh)
  cat <<EOS
function goenv {
  typeset command
EOS
  ;;
*)
  cat <<EOS
goenv() {
  local command
EOS
  ;;
esac

if [ "$shell" != "fish" ]; then
  IFS="|"
  cat <<EOS
  command="\$1"
  if [ "\$#" -gt 0 ]; then
    shift
  fi

  case "\$command" in
  ${commands[*]})
    eval "\$(goenv "sh-\$command" "\$@")";;
  *)
    command goenv "\$command" "\$@";;
  esac
}
EOS
fi

if [ -z "$no_rehash" ]; then
  # NOTE: Rehash again, but only to export managed paths
  cat <<EOS
  goenv rehash --only-manage-paths
EOS
fi

# Add automatic version detection on directory change (opt-in via GOENV_AUTOMATICALLY_DETECT_VERSION)
if [ -n "${GOENV_AUTOMATICALLY_DETECT_VERSION}" ] && [ "${GOENV_AUTOMATICALLY_DETECT_VERSION}" != "0" ]; then
  case "$shell" in
  fish)
    cat <<'EOS'
function __goenv_auto_detect_version --on-variable PWD
  if test -n "$GOENV_AUTOMATICALLY_DETECT_VERSION"; and test "$GOENV_AUTOMATICALLY_DETECT_VERSION" != "0"
    goenv rehash --only-manage-paths > /dev/null 2>&1
  end
end
EOS
    ;;
  zsh)
    cat <<'EOS'
__goenv_auto_detect_version() {
  if [ -n "${GOENV_AUTOMATICALLY_DETECT_VERSION}" ] && [ "${GOENV_AUTOMATICALLY_DETECT_VERSION}" != "0" ]; then
    eval "$(goenv rehash --only-manage-paths)"
  fi
}
if [[ ! "${chpwd_functions[*]}" =~ "__goenv_auto_detect_version" ]]; then
  chpwd_functions+=(__goenv_auto_detect_version)
fi
EOS
    ;;
  *)
    # bash, ksh, and other POSIX shells use PROMPT_COMMAND
    cat <<'EOS'
__goenv_auto_detect_version() {
  if [ -n "${GOENV_AUTOMATICALLY_DETECT_VERSION}" ] && [ "${GOENV_AUTOMATICALLY_DETECT_VERSION}" != "0" ]; then
    eval "$(goenv rehash --only-manage-paths)"
  fi
}
if [[ ! "${PROMPT_COMMAND}" =~ "__goenv_auto_detect_version" ]]; then
  if [ -n "${PROMPT_COMMAND}" ]; then
    PROMPT_COMMAND="${PROMPT_COMMAND};__goenv_auto_detect_version"
  else
    PROMPT_COMMAND="__goenv_auto_detect_version"
  fi
fi
EOS
    ;;
  esac
fi
